package com.qf.common.redis.aspect;

import com.qf.common.redis.annotation.MyLock;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

/**
 * @Classname MyLocklAspect
 * @Description TODO
 * @Date 2025-11-18 16:34
 * @Created by 老任与码
 */

/**
 * 面向切面编程：
 * 定义切点
 * 确定通知方法
 * <p>
 * 通知方法中的逻辑：
 * 获取注解对象
 * 根据注解对象获取属性值
 * 根据业务编写逻辑
 */
@Component
@Aspect
public class MyLocklAspect {

    @Resource
    private RedissonClient redissonClient;

    @Pointcut("@annotation(com.qf.common.redis.annotation.MyLock)")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) {
        //获取方法签名
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();

        // 获取注解对象
        MyLock annotation = method.getAnnotation(MyLock.class);
        if (annotation != null) {
            // 获取注解的属性
            String lockKey = annotation.lockKey();
            int waiteTime = annotation.waitTime();
            int leaseTime = annotation.leaseTime();

            RLock lock = redissonClient.getLock(lockKey);
            try {
                if (lock.tryLock(waiteTime, leaseTime, TimeUnit.SECONDS)) {
                    return joinPoint.proceed();
                }
            } catch (Throwable e) {
                throw new RuntimeException(e);
            } finally {
                if (lock.isHeldByCurrentThread() && lock.isLocked()) {
                    lock.unlock();
                }
            }
        } else {
            throw new RuntimeException("获取注解异常");
        }

        return null;
    }
}
